package br.net.woodstock.tickettoride.web.jsf.manager.common;

import java.util.ArrayList;
import java.util.Collection;

import javax.faces.model.SelectItem;

import br.net.woodstock.tickettoride.api.manager.ApplicationService;
import br.net.woodstock.tickettoride.api.manager.TicketService;
import br.net.woodstock.tickettoride.orm.Application;
import br.net.woodstock.tickettoride.orm.Ticket;
import br.net.woodstock.tickettoride.orm.UserType;
import br.net.woodstock.tickettoride.web.jsf.TTRBean;
import br.net.woodstock.tickettoride.web.jsf.security.common.JSFSecurityUtils;

public abstract class AbstractTicketBean extends TTRBean {

	private static final long		serialVersionUID				= 5227963963651906936L;

	private static final String		MAIN_VIEW						= "/manager/ticket.xhtml";

	private static final String		LIST_VIEW						= "/manager/ticket-list.xhtml";

	private static final String		DETAIL_VIEW						= "/manager/ticket-detail.xhtml";

	private static final String		MSG_ERROR_APPLICATION_REQUIRED	= "msg.error.application.required";

	private Integer					id;

	private Integer					fromApplicationId;

	private Integer					toApplicationId;

	private String					view;

	private String					ticketData;

	private boolean					listing;

	private Application				fromApplication;

	private Application				toApplication;

	private Ticket					ticket;

	private Collection<SelectItem>	applications;

	private Collection<Ticket>		tickets;

	public AbstractTicketBean() {
		super();
		this.view = AbstractTicketBean.LIST_VIEW;
	}

	public abstract ApplicationService getApplicationService();

	public abstract TicketService getTicketService();

	public String start() {
		this.onStart();
		if (JSFSecurityUtils.isUserInRole(UserType.ADMINISTRATOR.name())) {
			Collection<Application> collection = this.getApplicationService().listByFilter(null);
			this.applications = this.toSelectItem(collection);
		} else {
			Collection<Application> collection = this.getApplicationService().listByManager(JSFSecurityUtils.getSessionUser().getId(), null);
			this.applications = this.toSelectItem(collection);
		}
		this.fromApplicationId = null;
		this.toApplicationId = null;
		this.fromApplication = null;
		this.toApplication = null;
		this.tickets = null;
		return AbstractTicketBean.MAIN_VIEW;
	}

	public String end() {
		this.onEnd();
		return TTRBean.INDEX_VIEW;
	}

	public String list() {
		if (this.isValidId(this.fromApplicationId)) {
			this.fromApplication = this.getApplicationService().getById(this.fromApplicationId);
		} else {
			this.fromApplicationId = null;
		}
		if (this.isValidId(this.toApplicationId)) {
			this.toApplication = this.getApplicationService().getById(this.toApplicationId);
		} else {
			this.toApplicationId = null;
		}

		if ((!JSFSecurityUtils.isUserInRole(UserType.ADMINISTRATOR.name())) && (this.fromApplicationId == null) && (this.toApplicationId == null)) {
			this.addMessage(this.getMessage(AbstractTicketBean.MSG_ERROR_APPLICATION_REQUIRED));
			this.tickets = null;
			this.listing = false;
			return null;
		}

		this.tickets = this.getTicketService().listByApplication(this.fromApplicationId, this.toApplicationId);
		this.listing = true;
		return null;
	}

	public String show() {
		this.ticket = this.getTicketService().getById(this.id);
		this.ticketData = this.getTicketService().getPlainTicketData(this.id);
		this.view = AbstractTicketBean.DETAIL_VIEW;
		return null;
	}

	public String cancel() {
		if (JSFSecurityUtils.isUserInRole(UserType.ADMINISTRATOR.name())) {
			Collection<Application> collection = this.getApplicationService().listByFilter(null);
			this.applications = this.toSelectItem(collection);
		} else {
			Collection<Application> collection = this.getApplicationService().listByManager(JSFSecurityUtils.getSessionUser().getId(), null);
			this.applications = this.toSelectItem(collection);
		}
		this.fromApplicationId = null;
		this.toApplicationId = null;
		this.fromApplication = null;
		this.toApplication = null;
		this.tickets = null;
		this.listing = false;
		this.view = AbstractTicketBean.LIST_VIEW;
		return null;
	}

	public String back() {
		this.list();
		this.view = AbstractTicketBean.LIST_VIEW;
		return null;
	}

	private Collection<SelectItem> toSelectItem(final Collection<Application> collection) {
		if (collection == null) {
			return null;
		}
		Collection<SelectItem> items = new ArrayList<SelectItem>();
		for (Application a : collection) {
			items.add(new SelectItem(a.getId(), a.getName() + "(" + a.getAlias() + ")"));
		}
		return items;
	}
	
	// Getters and Setters
	public Integer getId() {
		return this.id;
	}

	public void setId(final Integer id) {
		this.id = id;
	}

	public Integer getFromApplicationId() {
		return this.fromApplicationId;
	}

	public void setFromApplicationId(final Integer fromApplicationId) {
		this.fromApplicationId = fromApplicationId;
	}

	public Integer getToApplicationId() {
		return this.toApplicationId;
	}

	public void setToApplicationId(final Integer toApplicationId) {
		this.toApplicationId = toApplicationId;
	}

	public void setView(final String view) {
		this.view = view;
	}

	public String getView() {
		return this.view;
	}

	public String getTicketData() {
		return this.ticketData;
	}

	public void setTicketData(final String ticketData) {
		this.ticketData = ticketData;
	}

	public boolean isListing() {
		return this.listing;
	}

	public void setListing(final boolean listing) {
		this.listing = listing;
	}

	public Ticket getTicket() {
		return this.ticket;
	}

	public void setTicket(final Ticket ticket) {
		this.ticket = ticket;
	}

	public Application getFromApplication() {
		return this.fromApplication;
	}

	public void setFromApplication(final Application fromApplication) {
		this.fromApplication = fromApplication;
	}

	public Application getToApplication() {
		return this.toApplication;
	}

	public void setToApplication(final Application toApplication) {
		this.toApplication = toApplication;
	}

	public Collection<SelectItem> getApplications() {
		return this.applications;
	}

	public void setApplications(final Collection<SelectItem> applications) {
		this.applications = applications;
	}

	public Collection<Ticket> getTickets() {
		return this.tickets;
	}

	public void setTickets(final Collection<Ticket> tickets) {
		this.tickets = tickets;
	}

}
